/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.web.frontendproject.generate;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.inspur.edp.web.common.customexception.WebCustomException;
import com.inspur.edp.web.common.entity.TerminalType;
import com.inspur.edp.web.common.environment.EnvironmentException;
import com.inspur.edp.web.common.io.FileUtility;
import com.inspur.edp.web.common.metadata.MetadataUtility;
import com.inspur.edp.web.common.serialize.SerializeUtility;
import com.inspur.edp.web.common.utility.StringUtility;
import com.inspur.edp.web.frontendproject.FrontendProjectManager;
import com.inspur.edp.web.frontendproject.FrontendProjectUtility;
import com.inspur.edp.web.frontendproject.customservice.SourceServicePathGenerator;
import com.inspur.edp.web.frontendproject.entity.FrontendProjectGenerateParameter;
import com.inspur.edp.web.frontendproject.metadata.FormMetadataManager;
import com.inspur.edp.web.jitengine.JITEngineManager;
import io.iec.edp.caf.commons.exception.ExceptionLevel;

import java.io.File;

/**
 * 前端工程代码生成
 *
 * @author guozhiqi
 */
public class FrontendProjectGenerate {
    public static void generateFrontendProject(String projectPath) {
        FrontendProjectGenerateParameter generateParameter = new FrontendProjectGenerateParameter();
        generateParameter.setProjectPath(projectPath);

        generateFrontendProject(generateParameter);
    }

    public static void generateFrontendProject(FrontendProjectGenerateParameter generateParameter) {
        String projectPath = FrontendProjectUtility.getProjectPathWithDevRootPath(generateParameter.getProjectPath());

        if (StringUtility.isNullOrEmpty(projectPath)) {
            throw new WebCustomException("Current Project Path is Null or Empty", ExceptionLevel.Warning);
        }
        // 调整工程路径参数
        generateParameter.setProjectPath(projectPath);

        try {

            TerminalType.rescure(terminalType -> {
                if (TerminalType.VUE.equals(terminalType)) {
                    return;
                }
                if (FormMetadataManager.checkFormMetadataExists(projectPath, terminalType, generateParameter.getBuildFormList(), generateParameter.isForceUseJieXi(), true)) {
                    generateFrontendProject(generateParameter, terminalType);
                }
            });

        } catch (EnvironmentException ex) {
            throw new WebCustomException(ex.getMessage(), ex);
        } catch (RuntimeException exception) {
            throw new WebCustomException(String.format("Error When Generating a Frontend Project. Current Project Path is: %1$s。%2$s", projectPath, exception.getMessage()), exception);
        }
    }


    public static void generateFrontendProject(String projectPath, TerminalType terminalType) {
        FrontendProjectGenerateParameter generateParameter = new FrontendProjectGenerateParameter();
        generateParameter.setProjectPath(projectPath);
        generateFrontendProject(generateParameter, terminalType);
    }

    public static void generateVueFrontendProject(String projectPath, TerminalType terminalType) {
        String sourceServiceProductPath = SourceServicePathGenerator.getSourceServiceProductPath(projectPath, terminalType, false);
        FrontendProjectManager.getInstance().buildVueFormTs(projectPath, sourceServiceProductPath);

        String sourceStyleProductPath = SourceServicePathGenerator.getSourceStyleProductPath(projectPath, terminalType);
        FrontendProjectManager.getInstance().buildVueFormScss(projectPath, sourceStyleProductPath);

    }

    /**
     * 基于解析后的表单代码生成前端工程
     */
    private static void generateFrontendProject(FrontendProjectGenerateParameter generateParameter, TerminalType terminalType) {
        boolean isJieXiForm = generateParameter != null && generateParameter.isForceUseJieXi();
        String devRootPath = MetadataUtility.getInstance().getDevRootPath();
        if (!FileUtility.isAbsolute(devRootPath)) {
            devRootPath = FileUtility.getAbsolutePathHead(devRootPath) + devRootPath;
        }
        JITEngineManager.generateFrontendProject(generateParameter, devRootPath, terminalType);

        String targetServiceProductPath = SourceServicePathGenerator.getTargetServiceProductPath(generateParameter.getProjectPath(), terminalType, isJieXiForm);

        String sourceServiceProductPath = SourceServicePathGenerator.getSourceServiceProductPath(generateParameter.getProjectPath(), terminalType, generateParameter.isForceUseJieXi());
        boolean isPathExists = FileUtility.exists(sourceServiceProductPath);
        if (isPathExists) {
            FileUtility.copyFolder(sourceServiceProductPath, targetServiceProductPath);
        }

        updatePackageJson(generateParameter, terminalType);
    }

    private static void updatePackageJson(FrontendProjectGenerateParameter generateParameter, TerminalType terminalType) {
        if(generateParameter == null){
            return;
        }
        boolean isJieXiForm = generateParameter.isForceUseJieXi();
        if(isJieXiForm){
            return;
        }

        String targetPackageJsonPath = SourceServicePathGenerator.getTargetPackageJsonPath(generateParameter.getProjectPath(), terminalType);
        String sourcePackageJsonPath = SourceServicePathGenerator.getSourcePackageJsonPath(generateParameter.getProjectPath(), terminalType);

        if(StringUtility.isNullOrEmpty(targetPackageJsonPath) || StringUtility.isNullOrEmpty(sourcePackageJsonPath)){
            return;
        }
        String sourceFileString = FileUtility.readAsString(sourcePackageJsonPath);
        String targetFileString = FileUtility.readAsString(targetPackageJsonPath);
        if(StringUtility.isNullOrEmpty(sourceFileString) || StringUtility.isNullOrEmpty(targetFileString)){
            return;
        }

        ObjectNode  sourcePackageJson = SerializeUtility.getInstance().deserialize(sourceFileString, ObjectNode.class);
        ObjectNode  targetPackageJson = SerializeUtility.getInstance().deserialize(targetFileString, ObjectNode.class);
        if(sourcePackageJson.get("dependencies") == null || targetPackageJson.get("dependencies") == null){
            return;
        }

        targetPackageJson.set("dependencies",sourcePackageJson.get("dependencies"));
        ObjectMapper mapper = new ObjectMapper();

        try {
            FileUtility.writeFile(targetPackageJsonPath, mapper.writerWithDefaultPrettyPrinter().writeValueAsString(targetPackageJson));
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

    }

}
